package hydrap2p.gui;

import hydrap2p.gui.commands.*;

import java.awt.Frame;
import java.awt.MenuItem;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.apache.thrift.TException;

public class GUIViewHandler extends JFrame implements WindowListener, ActionListener {

	private static volatile GUIViewHandler instance;
	private static int frameWidth = 1024;
	private static int frameHeight = 800;
	private static double horizontalDividerPercentage = 0.40;
	private static double verticalDividerPercentage = 0.20;
	private static int dividerSize = 3;
	
	private JScrollPane sidebarPanel;
	private JScrollPane mainPanel;
	private JTabbedPane swapPanel;
	private JSplitPane layout;
	private JSplitPane rightHalfLayout;
	
	private JScrollPane startupPanel;
	private JScrollPane limitPanel;
	private JSplitPane detailsPanel;
	private JSplitPane loggingPanel;
	private JSplitPane searchPanel;
	
	public static synchronized GUIViewHandler getInstance(){
		if(instance == null){
			synchronized (GUIViewHandler.class){
				if(instance == null){
					instance = new GUIViewHandler();
				}
			}
		}
		return instance;
	}
	
	private GUIViewHandler(){
		init();
	}
	
	private void init(){
		CommandInvoker.getInstance().invokeCommand(new Cmd_GUIViewHandler_LoadPreferences());
		
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
		
		setJMenuBar(createMenuBar());
		
		addWindowListener(this);
		
		sidebarPanel = FilterLabelPanel.getInstance();
		mainPanel = FileTransferPanel.getInstance();
		startupPanel = StartupManagerPanel.getInstance();
		limitPanel = SpeedLimiterPanel.getInstance();
		detailsPanel = DetailsPanel.getInstance();
		loggingPanel = LoggingPanel.getInstance();
		searchPanel = SearchPanel.getInstance();
				
		swapPanel = new JTabbedPane();
		swapPanel.addTab("Details", detailsPanel);
		swapPanel.addTab("Speed Limiter", limitPanel);
		swapPanel.addTab("Startup Manager", startupPanel);
		swapPanel.addTab("Logging", loggingPanel);	
		swapPanel.addTab("Search", searchPanel);	
		
		// Set up right half of the GUI
		rightHalfLayout = new JSplitPane(JSplitPane.VERTICAL_SPLIT, mainPanel, swapPanel);
		rightHalfLayout.setOneTouchExpandable(true);
		rightHalfLayout.setSize(frameWidth, frameHeight);
		rightHalfLayout.setDividerLocation(horizontalDividerPercentage);
		rightHalfLayout.setDividerSize(dividerSize);
	
		// Set up left half of the GUI
		layout = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sidebarPanel, rightHalfLayout);
		layout.setOneTouchExpandable(true);
		layout.setSize(frameWidth, frameHeight);
		layout.setDividerLocation(verticalDividerPercentage);
		layout.setDividerSize(dividerSize);
		
		// Set up GUI frame
		this.setTitle("HydraP2P");
		this.setVisible(true);
		this.setSize(frameWidth, frameHeight);
		this.setResizable(true);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		this.add(layout);
		
		this.validate();
		this.repaint();
		
		
		this.setVisible(true);
		
	}
	
	private JMenuBar createMenuBar()
	{
		JMenuBar mainBar = new JMenuBar();
		JMenu menu;
		JMenuItem mItem;
		
		menu = new JMenu("File");
		menu.setMnemonic(KeyEvent.VK_F);
		mainBar.add(menu);

		mItem = new JMenuItem("Add FTP download from URL...");
		mItem.setActionCommand("ftp");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Add HTTP download from URL...");
		mItem.setActionCommand("http");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Add BitTorrent download from URL...");
		mItem.setActionCommand("torrent");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Exit HydraP2P");
		mItem.setActionCommand("exit");
		mItem.addActionListener(this);
		menu.add(mItem);
		
		
		menu = new JMenu("View");
		menu.setMnemonic(KeyEvent.VK_V);
		mainBar.add(menu);

		mItem = new JMenuItem("Details");
		mItem.setActionCommand("details");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Speed Limiter");
		mItem.setActionCommand("limiter");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Startup Manager");
		mItem.setActionCommand("startup");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Logger");
		mItem.setActionCommand("logger");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Search");
		mItem.setActionCommand("search");
		mItem.addActionListener(this);
		menu.add(mItem);
		
		
		menu = new JMenu("Download");
		menu.setMnemonic(KeyEvent.VK_D);
		mainBar.add(menu);

		mItem = new JMenuItem("Pause");
		mItem.setActionCommand("pause");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Resume");
		mItem.setActionCommand("resume");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Edit Filter Labels...");
		mItem.setActionCommand("edit_label");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Change Priority...");
		mItem.setActionCommand("priority");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Remove");
		mItem.setActionCommand("remove");
		mItem.addActionListener(this);
		menu.add(mItem);
		
		
		menu = new JMenu("Label");
		menu.setMnemonic(KeyEvent.VK_L);
		mainBar.add(menu);

		mItem = new JMenuItem("Add New Label...");
		mItem.setActionCommand("add_label");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Delete Label");
		mItem.setActionCommand("delete_label");
		mItem.addActionListener(this);
		menu.add(mItem);
		
		
		menu = new JMenu("Module");
		menu.setMnemonic(KeyEvent.VK_M);
		mainBar.add(menu);

		mItem = new JMenuItem("Add Module...");
		mItem.setActionCommand("add_module");
		mItem.addActionListener(this);
		menu.add(mItem);
		mItem = new JMenuItem("Remove Module");
		mItem.setActionCommand("remove_module");
		mItem.addActionListener(this);
		menu.add(mItem);
		
		
		
		return mainBar;
	}
	
	public int getFrameWidth() {
		if(this.getExtendedState() == Frame.MAXIMIZED_HORIZ){
			return frameWidth;
		}else{
			return this.getWidth();
		}
	}

	public static void setFrameWidth(int width) {
		frameWidth = width;
	}

	public int getFrameHeight() {
		if(this.getExtendedState() == Frame.MAXIMIZED_VERT){
			return frameHeight;
		}else{
			return this.getHeight();
		}
	}

	public static void setFrameHeight(int height) {
		frameHeight = height;
	}

	public double getHorizontalDividerPercentage() {
		return (double)rightHalfLayout.getDividerLocation() / (double)this.getHeight();
	}

	public static void setHorizontalDividerPercentage(double pct) {
		horizontalDividerPercentage = pct;
	}

	public double getVerticalDividerPercentage() {
		return (double)layout.getDividerLocation() / (double)this.getWidth();
	}

	public static void setVerticalDividerPercentage(double pct) {
		verticalDividerPercentage = pct;
	}

	public void setSwapPanel(JPanel panel){
		int oldLocation = rightHalfLayout.getDividerLocation();
		
		rightHalfLayout.setBottomComponent(panel);
		rightHalfLayout.setDividerLocation(oldLocation);
		System.out.println(rightHalfLayout.getDividerSize());
		
		this.validate();
		this.repaint();
		
	}
	
	public void closeWindow() {
		WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
        Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
	}


	@Override
	public void windowActivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosed(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowClosing(WindowEvent e) {
		System.out.println("Window Closing");
		CommandInvoker.getInstance().invokeCommand(new Cmd_GUIViewHandler_SavePreferences());
		CommandInvoker.getInstance().invokeCommand(new Cmd_GUIViewHandler_UnsubscribeFromServices());
		
		// TODO Tell Manager to kill all modules 
		// TODO Figure out Minimize to Tray, etc.
	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowIconified(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void windowOpened(WindowEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		String action = arg0.getActionCommand();
		
		//File
		if (action.equals("ftp")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_AddURLToDownloadQueue());
		}else if (action.equals("http")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_AddURLToDownloadQueue());
		}else if (action.equals("torrent")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_AddBTToDownloadQueue());;
		}else if (action.equals("exit")){
			closeWindow();
		}
		
		//View
		else if (action.equals("details")){
			swapPanel.setSelectedIndex(0);
		}else if (action.equals("limiter")){
			swapPanel.setSelectedIndex(1);
		}else if (action.equals("startup")){
			swapPanel.setSelectedIndex(2);
		}else if (action.equals("logger")){
			swapPanel.setSelectedIndex(3);
		}else if (action.equals("search")){
			swapPanel.setSelectedIndex(4);
		}
		
		//Download
		else if (action.equals("pause")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_PauseTransfer());
		}else if (action.equals("resume")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_ResumeTransfer());
		}else if (action.equals("edit_label")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_EditFilterLabels());
		}else if (action.equals("priority")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_ChangeTransferPriority());;
		}else if (action.equals("remove")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FileTransferPanel_RemoveFromDownloads());
		}
		
		//Label
		else if (action.equals("add_label")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FilterLabelPanel_AddNewLabel());
		}else if (action.equals("delete_label")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_FilterLabelPanel_DeleteLabel());
		}
		
		//Module
		else if (action.equals("add_module")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_StartupManagerPanel_AddModule());
		}else if (action.equals("remove_module")){
			CommandInvoker.getInstance().invokeCommand(new Cmd_StartupManagerPanel_RemoveModule());
		}
	}
	
}
